#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

#include "spidev_interface.h"

#define PROGRAM_NAME "spidev_interface"

int init_spi(char const *dev_name)
{
    int fd;
    fd = open(dev_name, O_RDWR);
    if (fd < 0)
        errmsg_die("can't open device");
    return fd;
}

int set_spi_mode(int fd, uint32_t mode, int8_t bits, uint32_t speed)
{
    int ret;
    ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
    if (ret == -1)
        errmsg_die("can't get spi mode");
    /*
     * bits per word
     */
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1)
        errmsg_die("can't set bits per word");

    ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    if (ret == -1)
        errmsg_die("can't get bits per word");

    /*
     * max speed hz
     */
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1)
        errmsg_die("can't set max speed hz");

    ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
    if (ret == -1)
        errmsg_die("can't get max speed hz");
    return ret;
}

int close_spi(int fd)
{
    int ret = close(fd);
    if (ret < 0)
        errmsg_die("close()");
    return ret;
}

void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
    int ret;
    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx,
        .rx_buf = (unsigned long)rx,
        .len = len,
        .delay_usecs = 0,
    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
        errmsg_die("can't send spi message");
}
